package com.meisupic.copyright.service.impl;

import com.meisupic.copyright.common.MonitorStatusEnum;
import com.meisupic.copyright.domain.po.MonitorRecord;
import com.meisupic.copyright.domain.po.MonitorResult;
import com.meisupic.copyright.domain.query.MonitorQeury;
import com.meisupic.copyright.domain.vo.MonitorRecordVo;
import com.meisupic.copyright.domain.vo.MonitorResultVo;
import com.meisupic.copyright.repo.MonitorRecordRepo;
import com.meisupic.copyright.repo.MonitorResultRepo;
import com.meisupic.copyright.service.IMonitorService;
import com.meisupic.copyright.util.BeanMapper;
import com.meisupic.copyright.util.BeanUtil;
import com.meisupic.copyright.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * @Author lanjian
 * @Date 2018/3/15 下午3:20
 */
@Service
public class MonitorServiceImpl implements IMonitorService {

  @Autowired
  MonitorRecordRepo monitorRecordRepo;

  @Autowired
  MonitorResultRepo monitorResultRepo;


  @Override
  public MonitorRecordVo saveMonitorRecord(MonitorRecord monitorRecord) {
    if (!StringUtil.isEmpty(monitorRecord.getId())) {
      MonitorRecord existEntity = monitorRecordRepo.findOne(monitorRecord.getId());
      BeanUtil.copyPropertiesIgnoreNull(monitorRecord, existEntity);
      monitorRecord = monitorRecordRepo.save(existEntity);
    } else {
      monitorRecord = monitorRecordRepo.save(monitorRecord);
    }
    MonitorRecordVo monitorRecordVo = BeanMapper.map(monitorRecord, MonitorRecordVo.class);
    return monitorRecordVo;
  }

  @Override
  public boolean deleteMonitorRecore(Long id) {
    monitorRecordRepo.delete(id);
    return true;
  }

  /**
   * 更改监测状态
   */
  @Override
  public MonitorRecordVo changeStatus(Long id) {
    MonitorRecord monitorRecord = monitorRecordRepo.findOne(id);
    MonitorStatusEnum monitorStatusEnum = monitorRecord.getStatus();
    if (MonitorStatusEnum.running == monitorStatusEnum) {
      monitorRecord.setStatus(MonitorStatusEnum.stopped);
    } else {
      monitorRecord.setStatus(MonitorStatusEnum.running);
    }
    monitorRecordRepo.save(monitorRecord);
    MonitorRecordVo monitorRecordVo = BeanMapper.map(monitorRecord,MonitorRecordVo.class);
    return  monitorRecordVo;
  }

  @Override
  public Page<MonitorRecordVo> getPageMonitorRecord(MonitorQeury monitorQeury, Pageable pageable) {
    Specification<MonitorRecord> specification = createSpecification(monitorQeury);
    Page<MonitorRecord> page = monitorRecordRepo.findAll(specification, pageable);
    List<MonitorRecord> records = page.getContent();
    List<MonitorRecordVo> monitorRecordVos = BeanMapper.mapList(records, MonitorRecordVo.class);
    Page<MonitorRecordVo> recordVos = new PageImpl<>(monitorRecordVos, pageable,
        page.getTotalElements());
    return recordVos;
  }

  @Override
  public MonitorResultVo saveMonitorResult(MonitorResult monitorResult) {
    monitorResult = monitorResultRepo.save(monitorResult);
    MonitorResultVo monitorResultVo = BeanMapper.map(monitorResult, MonitorResultVo.class);
    return monitorResultVo;
  }

  @Override
  public Page<MonitorResultVo> getPageMonitorResult(MonitorResult monitorResult,
      Pageable pageable) {
    Page<MonitorResult> monitorResultPage = monitorResultRepo
        .findAll(Example.of(monitorResult), pageable);

    List<MonitorResult> monitorResults = monitorResultPage.getContent();
    List<MonitorResultVo> monitorResultVos = BeanMapper
        .mapList(monitorResults, MonitorResultVo.class);
    Page<MonitorResultVo> monitorResultVoPage = new PageImpl<>(monitorResultVos, pageable,
        monitorResultPage.getTotalElements());
    return monitorResultVoPage;
  }

  @Override
  public void ingoreResult(Long id) {
    MonitorResult monitorResult = monitorResultRepo.findOne(id);
    monitorResult.setIngoreStatus(true);
    monitorResultRepo.save(monitorResult);
  }


  private Specification<MonitorRecord> createSpecification(MonitorQeury query) {
    return new Specification<MonitorRecord>() {
      @Override
      public Predicate toPredicate(Root<MonitorRecord> root, CriteriaQuery<?> criteriaQuery,
          CriteriaBuilder criteriaBuilder) {
        List<Predicate> predicates = new ArrayList<>();

        if (!StringUtil.isEmpty(query.getUserId())) {
          predicates.add(criteriaBuilder.equal(root.get("userId"), query.getUserId()));
        }
        return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
      }
    };
  }
}
